home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / multipad.zip / MPFIND.C < prev    next >
Text File  |  1992-07-17  |  8KB  |  284 lines

  1. /***************************************************************************
  2.  *                                       *
  3.  *  MODULE    : MpFind.c                               *
  4.  *                                       *
  5.  *  PURPOSE    : Code to do text searches in MultiPad.            *
  6.  *                                       *
  7.  *  FUNCTIONS    : RealSlowCompare () - Compares subject string with target *
  8.  *                       string.                   *
  9.  *                                       *
  10.  *          MyFindText ()         - Looks for the search string in the  *
  11.  *                       active window.               *
  12.  *                                       *
  13.  *          FindPrev ()         - Find previous occurence of search   *
  14.  *                       string.                   *
  15.  *                                       *
  16.  *          FindNext ()         - Find next occurence of search string*
  17.  *                                       *
  18.  *          FindDlgProc ()     - Dialog function for Search/Find.    *
  19.  *                                       *
  20.  *          Find ()         - Invokes FindDlgProc ()           *
  21.  *                                       *
  22.  ***************************************************************************/
  23. // COPYRIGHT:
  24. //
  25. //   (C) Copyright Microsoft Corp. 1992.  All rights reserved.
  26. //
  27. //   You have a royalty-free right to use, modify, reproduce and
  28. //   distribute the Sample Files (and/or any modified version) in
  29. //   any way you find useful, provided that you agree that
  30. //   Microsoft has no warranty obligations or liability for any
  31. //   Sample Application Files which are modified.
  32.  
  33. #include "multipad.h"
  34.  
  35. #undef HIWORD
  36. #undef LOWORD
  37.  
  38. #define HIWORD(l) (((WORD*)&(l))[1])
  39. #define LOWORD(l) (((WORD*)&(l))[0])
  40.  
  41. BOOL fCase       = FALSE;    /* Turn case sensitivity off */
  42. char szSearch[160] = "";       /* Initialize search string  */
  43.  
  44. /****************************************************************************
  45.  *                                        *
  46.  *  FUNCTION   : RealSlowCompare ()                        *
  47.  *                                        *
  48.  *  PURPOSE    : Compares subject string with the target string. This fn/   *
  49.  *         is called repeatedly so that all substrings are compared,  *
  50.  *         which makes it O(n ** 2), hence it's name.                 *
  51.  *                                        *
  52.  *  RETURNS    : TRUE  - If pSubject is identical to pTarget.            *
  53.  *         FALSE - otherwise.                        *
  54.  *                                        *
  55.  ****************************************************************************/
  56.  
  57. BOOL NEAR PASCAL RealSlowCompare (pSubject, pTarget )
  58. register PSTR pSubject;
  59. register PSTR pTarget;
  60. {
  61.     if (fCase){
  62.     while (*pTarget)
  63.         if (*pTarget++ != *pSubject++)
  64.         return FALSE;
  65.     }
  66.     else{
  67.     /* If case-insensitive, convert both subject and target to lowercase
  68.      * before comparing.
  69.      */
  70.     AnsiLower ((LPSTR)pTarget);
  71.     while (*pTarget)
  72.         if (*pTarget++ != (char)(DWORD)AnsiLower ((LPSTR)(DWORD)(BYTE)*pSubject++))
  73.         return FALSE;
  74.     }
  75.     return TRUE;
  76. }
  77.  
  78. /****************************************************************************
  79.  *                                        *
  80.  *  FUNCTION   : MyFindText ()                            *
  81.  *                                        *
  82.  *  PURPOSE    : Finds the search string in the active window according to  *
  83.  *         search direction (dch) specified ( -1 for reverse and 1 for*
  84.  *         forward searches).                        *
  85.  *                                        *
  86.  ****************************************************************************/
  87. VOID NEAR PASCAL MyFindText( dch )
  88. register int dch;
  89.  
  90. {
  91.     register PSTR pText;
  92.     HANDLE      hT;
  93.     LONG      l;
  94.     WORD      cch;
  95.     int       i;
  96.  
  97.     if (!*szSearch)
  98.     return;
  99.  
  100.     /* Find the current selection range */
  101.     l = SendMessage(hwndActiveEdit, EM_GETSEL, 0, 0L);
  102.  
  103.     /* Get the handle to the text buffer and lock it */
  104.     hT      = (HANDLE)SendMessage (hwndActiveEdit, EM_GETHANDLE, 0, 0L);
  105.     pText = LocalLock(hT);
  106.  
  107.     /* Get the length of the text */
  108.     cch = (WORD)SendMessage (hwndActiveEdit, WM_GETTEXTLENGTH, 0, 0L);
  109.  
  110.     /* Start with the next char. in selected range ... */
  111.     pText += LOWORD (l) + dch;
  112.  
  113.     /* Compute how many characters are before/after the current selection*/
  114.     if (dch < 0)
  115.     i = LOWORD (l);
  116.     else
  117.     i = cch - LOWORD (l) + 1 - lstrlen (szSearch);
  118.  
  119.     /* While there are uncompared substrings... */
  120.     while ( i > 0){
  121.     LOWORD(l)+=dch;
  122.  
  123.     /* Does this substring match? */
  124.     if (RealSlowCompare(pText,szSearch)){
  125.  
  126.         /* Yes, unlock the buffer.*/
  127.         LocalUnlock(hT);
  128.  
  129.         /* Select the located string */
  130.         HIWORD(l) = LOWORD(l) + lstrlen (szSearch);
  131.         SendMessage (hwndActiveEdit, EM_SETSEL, 0, l);
  132.         return;
  133.     }
  134.     i--;
  135.  
  136.     /* increment/decrement start position by 1 */
  137.     pText += dch;
  138.     }
  139.  
  140.     /* Not found... unlock buffer. */
  141.     LocalUnlock (hT);
  142.  
  143.     /* Give a message */
  144.     MPError (hwndFrame, MB_OK | MB_ICONEXCLAMATION, IDS_CANTFIND, (LPSTR)szSearch);
  145.  
  146.     return;
  147. }
  148.  
  149. /****************************************************************************
  150.  *                                        *
  151.  *  FUNCTION   : FindPrev ()                            *
  152.  *                                        *
  153.  *  PURPOSE    : Finds the previous occurence of the search string. Calls   *
  154.  *         MyFindText () with a negative search direction.            *
  155.  *                                        *
  156.  ****************************************************************************/
  157. VOID FAR PASCAL FindPrev(void)
  158. {
  159.     MyFindText(-1);
  160. }
  161.  
  162. /****************************************************************************
  163.  *                                        *
  164.  *  FUNCTION   : FindNext ()                            *
  165.  *                                        *
  166.  *  PURPOSE    : Finds the next occurence of search string. Calls        *
  167.  *         MyFindText () with a positive search direction.            *
  168.  *                                        *
  169.  ****************************************************************************/
  170. VOID FAR PASCAL FindNext(void)
  171. {
  172.     MyFindText(1);
  173. }
  174.  
  175. /****************************************************************************
  176.  *                                        *
  177.  *  FUNCTION   : FindDlgProc(hwnd, message, wParam, lParam)            *
  178.  *                                        *
  179.  *  PURPOSE    : Dialog function for the Search/Find command. Prompts user  *
  180.  *         for target string, case flag and search direction.        *
  181.  *                                        *
  182.  ****************************************************************************/
  183. BOOL FAR PASCAL FindDlgProc(hwnd, msg, wParam, lParam)
  184. HWND hwnd;
  185. WORD msg;
  186. WORD wParam;
  187. LONG lParam;
  188. {
  189.     switch (msg){
  190.     case WM_INITDIALOG:{
  191.  
  192.         /* Check/uncheck case button */
  193.         CheckDlgButton (hwnd, IDD_CASE, fCase);
  194.  
  195.         /* Set default search string to most recently searched string */
  196.         SetDlgItemText (hwnd, IDD_SEARCH, szSearch);
  197.  
  198.         /* Allow search only if target is nonempty */
  199.         if (!lstrlen (szSearch)){
  200.         EnableWindow (GetDlgItem (hwnd, IDOK), FALSE);
  201.         EnableWindow (GetDlgItem (hwnd, IDD_PREV), FALSE);
  202.         }
  203.         break;
  204.     }
  205.  
  206.     case WM_COMMAND:{
  207.  
  208.         /* Search forward by default (see IDOK below) */
  209.         int i = 1;
  210.  
  211.         switch (wParam){
  212.         /* if the search target becomes non-empty, enable searching */
  213.         case IDD_SEARCH:
  214.             if (HIWORD (lParam) == EN_CHANGE){
  215.             if (!(WORD) SendDlgItemMessage (hwnd,
  216.                             IDD_SEARCH,
  217.                             WM_GETTEXTLENGTH,
  218.                             0,
  219.                             0L))
  220.                 i = FALSE;
  221.             else
  222.                 i = TRUE;
  223.             EnableWindow (GetDlgItem (hwnd, IDOK), i);
  224.             EnableWindow (GetDlgItem (hwnd, IDD_PREV), i);
  225.             }
  226.             break;
  227.  
  228.         case IDD_CASE:
  229.             /* Toggle state of case button */
  230.             CheckDlgButton (hwnd,
  231.                     IDD_CASE,
  232.                     !IsDlgButtonChecked (hwnd, IDD_CASE));
  233.             break;
  234.  
  235.         case IDD_PREV:
  236.             /* Set direction to backwards */
  237.             i=-1;
  238.             /*** FALL THRU ***/
  239.  
  240.         case IDOK:
  241.             /* Save case selection */
  242.             fCase = IsDlgButtonChecked( hwnd, IDD_CASE);
  243.  
  244.             /* Get search string */
  245.             GetDlgItemText (hwnd, IDD_SEARCH, szSearch, sizeof (szSearch));
  246.  
  247.             /* Find the text */
  248.             MyFindText (i);
  249.             /*** FALL THRU ***/
  250.  
  251.         /* End the dialog */
  252.         case IDCANCEL:
  253.             EndDialog (hwnd, 0);
  254.             break;
  255.  
  256.         default:
  257.             return FALSE;
  258.         }
  259.         break;
  260.     }
  261.     default:
  262.         return FALSE;
  263.     }
  264.     return TRUE;
  265. }
  266.  
  267. /****************************************************************************
  268.  *                                        *
  269.  *  FUNCTION   : Find()                             *
  270.  *                                        *
  271.  *  PURPOSE    : Invokes the Search/Find dialog.                *
  272.  *                                        *
  273.  ****************************************************************************/
  274.  
  275. VOID FAR PASCAL Find()
  276. {
  277.     FARPROC lpfn;
  278.  
  279.     lpfn = MakeProcInstance (FindDlgProc, hInst);
  280.     DialogBox (hInst, IDD_FIND, hwndFrame, lpfn);
  281.     FreeProcInstance (lpfn);
  282. }
  283. 
  284.